home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / CBASE102.ARJ / CBLOCK.C < prev    next >
Text File  |  1991-09-23  |  5KB  |  201 lines

  1. /*    Copyright (c) 1989 Citadel    */
  2. /*       All Rights Reserved        */
  3.  
  4. /* #ident    "@(#)cblock.c    1.5 - 91/09/23" */
  5.  
  6. #include <ansi.h>
  7.  
  8. /* ansi headers */
  9. #include <errno.h>
  10.  
  11. /* library headers */
  12. #include <btree.h>
  13. #include <lseq.h>
  14.  
  15. /* local headers */
  16. #include "cbase_.h"
  17.  
  18. /*man---------------------------------------------------------------------------
  19. NAME
  20.      cblock - lock cbase
  21.  
  22. SYNOPSIS
  23.      #include <cbase.h>
  24.  
  25.      int cblock(cbp, ltype)
  26.      cbase_t *cbp;
  27.      int ltype;
  28.  
  29. DESCRIPTION
  30.      The cblock function controls the lock status of a cbase.  The cbp
  31.      argument is an open cbase.  ltype indicates the target status of
  32.      the lock on the cbase.
  33.  
  34.      The lock types available are:
  35.  
  36.      CB_UNLCK       unlock cbase
  37.      CB_RDLCK       lock cbase for reading
  38.      CB_WRLCK       lock cbase for reading and writing
  39.      CB_RDLKW       lock cbase for reading (wait)
  40.      CB_WRLKW       lock cbase for reading and writing (wait)
  41.  
  42.      For the lock types which wait, cblock will not return until the
  43.      lock is available.  For the lock types which do not wait, if the
  44.      lock is unavailable because of a lock held by another process  a
  45.      value of -1 is returned and errno set to EAGAIN.
  46.  
  47.      cblock will fail if one or more of the following is true:
  48.  
  49.      [EAGAIN]       ltype is CB_RDLCK and the cbase is
  50.                     already write locked by another process,
  51.                     or ltype is CB_WRLCK and the cbase is
  52.                     already read or write locked by another
  53.                     process.
  54.      [EINVAL]       cbp is is not a valid cbase.
  55.      [EINVAL]       ltype is not a valid lock type.
  56.      [CBECORRUPT]   Either the record file or one of the index
  57.                     files of cbp is corrupt.
  58.      [CBENOPEN]     cbp is not open.
  59.      [CBENOPEN]     ltype is CB_RDLCK or CB_RDLKW and cbp
  60.                     is not opened for reading or ltype is
  61.                     CB_WRLCK or CB_WRLKW and cbp not open
  62.                     for writing.
  63.  
  64. SEE ALSO
  65.      cbgetlck.
  66.  
  67. DIAGNOSTICS
  68.      Upon successful completion, a value of 0 is returned.  Otherwise,
  69.      a value of -1 is returned, and errno set to indicate the error.
  70.  
  71. ------------------------------------------------------------------------------*/
  72. #ifdef AC_PROTO
  73. int cblock(cbase_t *cbp, int ltype)
  74. #else
  75. int cblock(cbp, ltype)
  76. cbase_t *cbp;
  77. int ltype;
  78. #endif
  79. {
  80.     int    btltype    = 0;        /* btree lock type */
  81.     int    i    = 0;        /* loop counter */
  82.     int    lsltype    = 0;        /* lseq lock type */
  83.  
  84.     /* validate arguments */
  85.     if (!cb_valid(cbp)) {
  86.         errno = EINVAL;
  87.         return -1;
  88.     }
  89.  
  90.     /* check if cbase not open */
  91.     if (!(cbp->flags & CBOPEN)) {
  92.         errno = CBENOPEN;
  93.         return -1;
  94.     }
  95.  
  96.     /* check open flags and set lsltype and btltype */
  97.     switch (ltype) {
  98.     case CB_RDLCK:
  99.         if (!(cbp->flags & CBREAD)) {
  100.             errno = CBENOPEN;
  101.             return -1;
  102.         }
  103.         lsltype = LS_RDLCK;
  104.         btltype = BT_RDLCK;
  105.         break;
  106.     case CB_RDLKW:
  107.         if (!(cbp->flags & CBREAD)) {
  108.             errno = CBENOPEN;
  109.             return -1;
  110.         }
  111.         lsltype = LS_RDLKW;
  112.         btltype = BT_RDLKW;
  113.         break;
  114.     case CB_WRLCK:
  115.         if (!(cbp->flags & CBWRITE)) {
  116.             errno = CBENOPEN;
  117.             return -1;
  118.         }
  119.         lsltype = LS_WRLCK;
  120.         btltype = BT_WRLCK;
  121.         break;
  122.     case CB_WRLKW:
  123.         if (!(cbp->flags & CBWRITE)) {
  124.             errno = CBENOPEN;
  125.             return -1;
  126.         }
  127.         lsltype = LS_WRLKW;
  128.         btltype = BT_WRLKW;
  129.         break;
  130.     case CB_UNLCK:
  131.         lsltype = LS_UNLCK;
  132.         btltype = BT_UNLCK;
  133.         break;
  134.     default:
  135.         errno = EINVAL;
  136.         return -1;
  137.         break;
  138.     }
  139.  
  140.     /* unlock in reverse order of locking */
  141.     if (ltype == CB_UNLCK) {
  142.         /* unlock index files */
  143.         for (i = cbp->fldc - 1; i >= 0; --i) {
  144.             if (cbp->fldv[i].flags & CB_FKEY) {
  145.                 if (btlock(cbp->btpv[i], btltype) == -1) {
  146.                     CBEPRINT;
  147.                     return -1;
  148.                 }
  149.             }
  150.         }
  151.     }
  152.  
  153.     /* lock data file */
  154.     if (lslock(cbp->lsp, lsltype) == -1) {
  155.         if (errno == EAGAIN) {
  156.             return -1;
  157.         }
  158.         if (errno == LSECORRUPT) {
  159.             errno = CBECORRUPT;
  160.             return -1;
  161.         }
  162.         CBEPRINT;
  163.         return -1;
  164.     }
  165.  
  166.     if (ltype != CB_UNLCK) {
  167.         /* lock index files */
  168.         for (i = 0; i < cbp->fldc; ++i) {
  169.             if (cbp->fldv[i].flags & CB_FKEY) {
  170.                 if (btlock(cbp->btpv[i], btltype) == -1) {
  171.                     CBEPRINT;
  172.                     return -1;
  173.                 }
  174.             }
  175.         }
  176.     }
  177.  
  178.     /* set lock bits */
  179.     switch (ltype) {
  180.     case CB_RDLCK:
  181.     case CB_RDLKW:
  182.         cbp->flags |= CBRDLCK;
  183.         cbp->flags &= ~CBWRLCK;
  184.         break;
  185.     case CB_WRLCK:
  186.     case CB_WRLKW:
  187.         cbp->flags |= (CBRDLCK | CBWRLCK);
  188.         break;
  189.     case CB_UNLCK:
  190.         cbp->flags &= ~CBLOCKS;
  191.         break;
  192.     default:
  193.         CBEPRINT;
  194.         errno = CBEPANIC;
  195.         return -1;
  196.         break;
  197.     }
  198.  
  199.     return 0;
  200. }
  201.